#ifndef _E_ENTITY_H_
#define _E_ENTITY_H_

#include "EVector.h"
#include "ESceneObject.h"
#include "EGameObject.h"
#include "eH.h"

namespace engine
{
class EEntity : public EGameObject
{

  friend class EEntityManager;

  string            m_sName;
  bool              m_bIsVisible;
  bool              m_bCastShadows;

  // 3D engine entity
  string            m_sModelFileName;
  Entity*           m_pOgreEntity;
  
  SceneManager*     m_pOgreSceneManager;

  // 3D engine animation
  AnimationState*   m_pOgreAnimationState;
protected:
  SceneNode*        m_pOgreNode;
  EVector           m_vPosition;
  EVector           m_vScale;

public:
  /// order is important : it is the order of the update sequence calls
  enum _eGroupType
  {
    ENTITY_GROUP_STATIC = 0,
    ENTITY_GROUP_COLLIDERS,
    ENTITY_GROUP_CHARACTER,
    ENTITY_GROUP_LIGHT,
    ENTITY_GROUP_CAMERA,
    ENTITY_GROUP_COUNT
  };

protected:
  EEntity( _eGroupType eGroupType );
  EEntity( _eGroupType eGroupType, const string& sName );
  EEntity( _eGroupType eGroupType, const string& sName, const string& sModelFileName);

public:

  inline string   getNodeName       () const;
  virtual bool    load              ( SceneManager& sceneManager );
  virtual bool    update            ( const EGameTime& time );
  virtual bool    startGame         ( ) { return true; }
  virtual bool    updateGame        ( const EGameTime& time ) { return true; }
  virtual bool    endGame           ( ) { return true; }
  void            setPosition       ( const EVector& vPos );
  void            setPosition       ( float fX, float fY, float fZ );
  void            setScale          ( const EVector& vScale );
  void            setScale          ( float fSX, float fSY, float fSZ );
  void            setScale          ( float fSXYZ );
  inline const EVector& getPosition       () const { return m_vPosition; }
  inline const EVector& getScale          () const { return m_vScale; }
  bool            setAnimationState ( const string& sState, bool bLoop = true );
  AnimationState* getAnimationState () const { return m_pOgreAnimationState; }
  void            enableAnimation   ( bool bEnabled );

  inline Entity*      getOgreEntity () const { return m_pOgreEntity; }
  const MeshPtr&      getOgreMesh   () const;
  inline SceneNode*   getOgreNode   () const { return m_pOgreNode; }

};
} // end namespace

#endif